using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Sockets;

namespace SPI.AgentServer.Controllers;

/// <summary>
/// 健康检查控制器
/// 用于监控服务和依赖项的健康状态
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class HealthController : ControllerBase
{
    private readonly ILogger<HealthController> _logger;
    private readonly IConfiguration _configuration;
    private readonly IHttpClientFactory _httpClientFactory;

    public HealthController(
        ILogger<HealthController> logger, 
        IConfiguration configuration,
        IHttpClientFactory httpClientFactory)
    {
        _logger = logger;
        _configuration = configuration;
        _httpClientFactory = httpClientFactory;
    }

    /// <summary>
    /// 基础健康检查
    /// </summary>
    /// <returns>服务状态</returns>
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            status = "healthy",
            timestamp = DateTime.UtcNow,
            service = "SPI.AgentServer",
            version = "1.0.0"
        });
    }

    /// <summary>
    /// 详细健康检查（包含依赖项）
    /// </summary>
    /// <returns>详细的健康状态信息</returns>
    [HttpGet("detailed")]
    public async Task<IActionResult> GetDetailed()
    {
        var qwenCheck = await CheckQwenConnection();
        var dbCheck = CheckDatabaseConfiguration();
        var sshCheck = CheckSshTunnel();

        var health = new
        {
            status = "healthy",
            timestamp = DateTime.UtcNow,
            service = "SPI.AgentServer",
            version = "1.0.0",
            checks = new
            {
                qwen = qwenCheck,
                database = dbCheck,
                sshTunnel = sshCheck
            }
        };

        var allHealthy = qwenCheck.Healthy && dbCheck.Healthy && sshCheck.Healthy;

        return allHealthy ? Ok(health) : StatusCode(503, health);
    }

    /// <summary>
    /// 检查Qwen API连接
    /// </summary>
    private async Task<HealthCheckResult> CheckQwenConnection()
    {
        try
        {
            var useMock = _configuration.GetValue<bool>("Qwen:UseMock");
            if (useMock)
            {
                return new HealthCheckResult { Healthy = true, Message = "使用Mock模式，跳过连接检查" };
            }

            var baseUrl = _configuration["Qwen:BaseUrl"] ?? "";
            var uri = new Uri(baseUrl);
            
            // 简单的TCP连接测试
            using var client = new TcpClient();
            var connectTask = client.ConnectAsync(uri.Host, uri.Port);
            var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
            
            var completedTask = await Task.WhenAny(connectTask, timeoutTask);
            
            if (completedTask == connectTask && client.Connected)
            {
                return new HealthCheckResult { Healthy = true, Message = "Qwen API 可访问", Endpoint = baseUrl };
            }
            else
            {
                return new HealthCheckResult { Healthy = false, Message = "Qwen API 连接超时", Endpoint = baseUrl };
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Qwen连接检查失败");
            return new HealthCheckResult { Healthy = false, Message = $"连接失败: {ex.Message}" };
        }
    }

    /// <summary>
    /// 检查数据库配置
    /// </summary>
    private HealthCheckResult CheckDatabaseConfiguration()
    {
        try
        {
            var useMock = _configuration.GetValue<bool>("Database:UseMock");
            var connections = _configuration.GetSection("Database:Connections").GetChildren().Count();
            
            return new HealthCheckResult
            { 
                Healthy = true, 
                Message = useMock ? "使用Mock数据库" : "使用真实数据库",
                Mode = useMock ? "Mock" : "Real",
                ConfiguredConnections = connections
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "数据库配置检查失败");
            return new HealthCheckResult { Healthy = false, Message = $"配置错误: {ex.Message}" };
        }
    }

    /// <summary>
    /// 检查SSH隧道状态
    /// </summary>
    private HealthCheckResult CheckSshTunnel()
    {
        try
        {
            var connectionMode = _configuration["Qwen:ConnectionMode"] ?? "direct";
            var sshEnabled = _configuration.GetValue<bool>("Qwen:SshTunnel:Enabled");
            
            if (!sshEnabled || !connectionMode.Equals("ssh", StringComparison.OrdinalIgnoreCase))
            {
                return new HealthCheckResult { Healthy = true, Message = "SSH隧道未启用", Mode = connectionMode };
            }

            // 检查SSH隧道端口
            var localPort = _configuration.GetValue<int>("Qwen:SshTunnel:LocalPort", 23333);
            
            try
            {
                using var client = new TcpClient();
                var result = client.BeginConnect("localhost", localPort, null, null);
                var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromMilliseconds(500));
                
                if (success)
                {
                    client.EndConnect(result);
                    return new HealthCheckResult { Healthy = true, Message = "SSH隧道正常", Port = localPort };
                }
                else
                {
                    return new HealthCheckResult { Healthy = false, Message = "SSH隧道端口不可用", Port = localPort };
                }
            }
            catch
            {
                return new HealthCheckResult { Healthy = false, Message = "SSH隧道连接失败", Port = localPort };
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "SSH隧道检查失败");
            return new HealthCheckResult { Healthy = false, Message = $"检查失败: {ex.Message}" };
        }
    }

    /// <summary>
    /// 快速存活检查（用于负载均衡器）
    /// </summary>
    [HttpGet("alive")]
    public IActionResult Alive()
    {
        return Ok(new { status = "alive", timestamp = DateTime.UtcNow });
    }

    /// <summary>
    /// 就绪检查（检查服务是否准备好处理请求）
    /// </summary>
    [HttpGet("ready")]
    public async Task<IActionResult> Ready()
    {
        try
        {
            var qwenCheck = await CheckQwenConnection();
            
            if (qwenCheck.Healthy)
            {
                return Ok(new { status = "ready", timestamp = DateTime.UtcNow });
            }
            else
            {
                return StatusCode(503, new { status = "not ready", reason = "Qwen API 不可用" });
            }
        }
        catch
        {
            return StatusCode(503, new { status = "not ready" });
        }
    }
}

/// <summary>
/// 健康检查结果
/// </summary>
public class HealthCheckResult
{
    public bool Healthy { get; set; }
    public string Message { get; set; } = string.Empty;
    public string? Endpoint { get; set; }
    public string? Mode { get; set; }
    public int? ConfiguredConnections { get; set; }
    public int? Port { get; set; }
}

